home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ADA Programming Guide
/
ADA Programming Guide.iso
/
ada_gwu
/
cwktask.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-01-30
|
20KB
|
733 lines
/*
GWMON Parallel Ada Monitor for 386/486 PCs
Copyright (C) 1993, Charles W. Kann & Michael Bliss Feldman
ckann@seas.gwu.edu mfeldman@seas.gwu.edu
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "ed.h"
#include "keydef.h"
/*
I need the variable "exception_trace" from ivars.h. I don't want
to use the whole .h, so I am including this one variable here.
*/
extern int exception_trace;
static int current_task;
static int save_block_number = -1;
static long Run_Current_Time; /* Run time (lines) since last report */
extern rr_flag;
void CWK_SET_TASK();
void CWK_SET_TASK_LINE();
void CWK_GET_KEY();
static void scroll_tasks();
void busy_wait(wait_cnt)
int wait_cnt;
{
int i, cycles;
cycles = delay_scaling_factor * delay_array[wait_cnt];
for ( i = 0; i < cycles; ++i );
}
void CWK_CREATE_TASK(task_no, task_name, task_file)
int task_no;
char *task_name;
char *task_file;
{
char msg[100];
int ch;
if ( task_no > MAX_TSKS ) {
printf("Can't work with more than %d tasks...", MAX_TSKS-1);
}
/*
Find the task particulars in the task file (For now, hard code them)
*/
CWK_TASKS[task_no].TN = malloc( strlen(task_name)+1 );
strcpy( CWK_TASKS[task_no].TN, task_name );
CWK_TASKS[task_no].FL = 1;
CWK_TASKS[task_no].LL = 10000;
CWK_TASKS[task_no].FLOS = 0;
CWK_TASKS[task_no].CL = 0;
CWK_TASKS[task_no].MON = CWK_CREATE_MON_WIN(CWK_TASKS[task_no].TN,
(monitor_type == 1) ? 1 : 0 );
CWK_TASKS[task_no].FD = CWK_LOAD_FILE(task_file);
}
/*************************************************************************/
/* */
/* CWK_Switch_Block is used to make sure the correct program block */
/* (ie procedure, package, task, etc) is being used. When a program*/
/* block becomes current, we want to make sure that we then move to */
/* use that program block. Program blocks are entered and exited */
/* inta.c. We call this routine from there. */
/* */
/* parameters: */
/* block_number : the block number of this block */
/* block_name : the title of the block (ie proc name) */
/* block_file : file which contains this block */
/* enter_or_exit: Are we entering or exiting this block */
/* This is only used in procedure monitoring */
/* If this is 1 - exiting, 0 - entering */
/* */
/*************************************************************************/
CWK_Switch_Block( block_number, block_name, block_package, block_file,
enter_or_exit )
int block_number, enter_or_exit;
char *block_name, *block_package, *block_file;
{
FILE_REC_PTR Save_FD;
char package_routine[68];
/*
In the case of task monitoring, if the new procedure is in
a different source file from the one currently being used,
move to that source file.
*/
if ( task_monitor )
{
Save_FD = CWK_TASKS[current_task].FD;
CWK_TASKS[current_task].FD = CWK_LOAD_FILE(block_file);
if ( Save_FD != CWK_TASKS[current_task].FD )
CWK_TASKS[current_task].FLOS = 0;
}
/*
Procedure monitoring
*/
else
{
/*
The save_block_number remembers the block between
calls. The first time through, however, it must be set
*/
if ( save_block_number == -1 )
save_block_number = block_number;
/*
If this block hasn't been created, and we have a valid
block, create it. If the block is part of a package,
prepend the package name.
*/
if ( strcmp( block_package, "main" ) != 0 )
{
strcpy( package_routine, block_package );
strcat( package_routine, "." );
strcat( package_routine, block_name );
}
else
strcpy( package_routine, block_name );
if ( CWK_BLKS[block_number].MON == NULL )
CWK_CREATE_BLOCK(block_number, package_routine,
block_file );
/*
Only worry about monitor windows if the monitor is
running.
*/
if ( monitor_type != 1 )
return;
if ( monitor_window_type == 3 )
{
save_block_number = block_number;
CWK_DRAW_PROC_WIN( CWK_BLKS[block_number].MON,
enter_or_exit );
CWK_BLKS[save_block_number].FLOS = 0;
#if 0
CWK_SET_TASK_LINE( CWK_BLKS[block_number].CL, 0 );
#endif
/*
If the mode is to be in task step mode,
then wait for a key to be pressed to
move to the next step, otherwise, wait
a second to keep the screen from flashing.
*/
if ( task_step )
CWK_GET_KEY( 1 );
else
busy_wait( MAX_DELAY-1 );
}
else
save_block_number = block_number;
}
}
CWK_LEAVE_BLOCK( block_number )
int block_number;
{
if ( monitor_type != 1 )
return;
if ( ! task_monitor )
CWK_REMOVE_BLOCK( CWK_BLKS[block_number].MON);
}
/*************************************************************************/
/*************************************************************************/
void CWK_DISTROY_TASK(task_no)
int task_no;
{
CWK_TASKS[task_no].TN = "";
CWK_TASKS[task_no].FL = 0;
CWK_TASKS[task_no].LL = 0;
CWK_DEL_MON_WIN(CWK_TASKS[task_no].MON);
}
void CWK_CHANGE_TASK_STAT(task_no, stat, task_name, task_file )
int task_no;
char stat;
char *task_name, *task_file;
{
int FLOS;
FLOS = CWK_TASKS[task_no].FLOS;
if ( ! task_monitor )
return;
CWK_TASKS[task_no].ST = stat;
switch( stat ) {
case 'C' : /* Create a new task */
CWK_CREATE_TASK( task_no, task_name, task_file );
CWK_TASKS[task_no].ST = '*';
break;
case 'A' : /* Activate a task */
CWK_SET_TASK( task_no );
CWK_TASKS[task_no].ST = '*';
if ( ( task_step ) && ( CWK_TASKS[task_no].MON->WON == 1 ) )
CWK_GET_KEY( 1 );
break;
case 'S' : /* Change to a new task */
CWK_SET_TASK( task_no );
CWK_TASKS[task_no].ST = '*';
break;
case 'D' : /* Delaying task */
if ( monitor_type == 1 )
{
CWK_CUR_LINE( CWK_TASKS[task_no].MON,
CWK_TASKS[task_no].CL- FLOS, " D " );
if ( ( task_step ) &&
( CWK_TASKS[task_no].MON->WON == 1 ) )
CWK_GET_KEY( 1 );
}
break;
case 'R' : /* Waiting Rendezvous */
if ( monitor_type == 1 )
{
CWK_CUR_LINE( CWK_TASKS[task_no].MON,
CWK_TASKS[task_no].CL- FLOS, " R " );
if ( ( task_step ) &&
( CWK_TASKS[task_no].MON->WON == 1 ) )
CWK_GET_KEY( 1 );
}
break;
case 'M' : /* Rendezvous Met */
if ( monitor_type == 1 )
{
CWK_CUR_LINE( CWK_TASKS[task_no].MON,
CWK_TASKS[task_no].CL- FLOS, " M " );
if ( ( task_step ) &&
( CWK_TASKS[task_no].MON->WON == 1 ) )
CWK_GET_KEY( 1 );
}
break;
case 'E' : /* Rendezvous Met */
CWK_DISTROY_TASK( task_no );
break;
}
}
void CWK_SET_TASK_LINE( line_no, getkey_or_not )
int line_no, getkey_or_not;
{
int i;
int FLOS;
static text_string[50], format_string[50];
TASK_REC *temp_task;
int task_no;
if ( task_monitor )
{
task_no = current_task;
temp_task = CWK_TASKS;
}
else
{
task_no = save_block_number;
temp_task = CWK_BLKS;
}
if ( temp_task[task_no].FD->lines_in_file < line_no )
{
return;
}
if ( ( temp_task[task_no].MON->WON != 1 ) ||
( monitor_type != 1 ) )
{
return;
}
FLOS = temp_task[task_no].FLOS;
if ( FLOS != 0 )
CWK_CUR_LINE(temp_task[task_no].MON,
temp_task[task_no].CL - FLOS, " ");
if (( FLOS == 0 ) ||
(( line_no < FLOS ) || (line_no > FLOS + WIN_SIZE))) {
FLOS = line_no - (WIN_SIZE / 2);
if (FLOS < 1)
FLOS = 1;
temp_task[task_no].FLOS = FLOS;
for ( i = 0; i < WIN_SIZE; ++i )
{
/* Blank out the current line */
CWK_CUR_LINE(temp_task[task_no].MON, i+1, " ");
sprintf( format_string,"%c%d.%ds", '%',
LINE_SIZE+4-Block_Level,
LINE_SIZE+4-Block_Level );
sprintf( text_string, format_string, " " );
CWK_WRITE_LINE(temp_task[task_no].MON, i+1,
text_string );
#if 0
if ( ( monitor_window_type == 0 ) ||
( monitor_window_type == 2 ) )
CWK_WRITE_LINE(temp_task[task_no].MON, i+1,
" " );
else
CWK_WRITE_LINE(temp_task[task_no].MON, i+1,
" " );
#endif
/* Stop putting out lines when you have reached */
/* the end of the file so you don't access bad */
/* memory */
if (temp_task[task_no].FD->lines_in_file <
FLOS+i)
{
continue;
}
/* Now write out the line to the screen. Note that */
/* the use of different window types was stuffed in */
/* later int he program life, and so the string size*/
/* for a window is handled here, not in cwkgraph */
/* where it belongs! */
sprintf( format_string,"%c3.3d %c-%d.%ds", '%', '%',
LINE_SIZE-Block_Level, LINE_SIZE-Block_Level );
sprintf( text_string, format_string, FLOS+i,
temp_task[task_no].FD->lines[FLOS+i]);
#if 0
if ( ( monitor_window_type == 0 ) ||
( monitor_window_type == 2 ) )
sprintf( text_string, "%3.3d %-28.28s", FLOS+i,
temp_task[task_no].FD->lines[FLOS+i]);
else
sprintf( text_string, "%3.3d %-68.68s", FLOS+i,
temp_task[task_no].FD->lines[FLOS+i]);
#endif
CWK_WRITE_LINE(temp_task[task_no].MON, i+1,
text_string);
}
}
temp_task[task_no].CL = line_no;
CWK_CUR_LINE(temp_task[task_no].MON, line_no - FLOS, "-->");
if ( getkey_or_not )
CWK_GET_KEY( 0 );
}
void CWK_SET_TASK(task_no)
int task_no;
{
int ch;
current_task = task_no;
}
/***********************************************************************/
/* This section of code handles the control screen . */
/***********************************************************************/
void print_status()
{
int iline;
int save_current_task;
if ( rr_flag )
CWK_CONTROL_TASK( "Round Robin", CWK_TASKS[current_task].TN,
Run_Total_Time, 0 );
else
CWK_CONTROL_TASK( "Run til blk", CWK_TASKS[current_task].TN,
Run_Total_Time, 0 );
scroll_tasks();
CWK_ERASE_ALL_MON_WIN();
/*
Save the current task. This is because I want to use the
routine CWK_SET_TASK_LINE to redraw the windows. It requires
current_task to be the task redrawn. So I set it in the loop,
and at the end restore the value.
*/
save_current_task = current_task;
for ( iline = 0; iline < MAX_TSKS; ++iline ) {
if ( CWK_TASKS[iline].TN != NULL ) {
#if 0
CWK_TASKS[iline].Cur_Time = 0;
#endif
if ( CWK_TASKS[iline].MON->WON == 1 ) {
current_task = iline;
CWK_DRAW_MON_WIN( CWK_TASKS[iline].MON );
CWK_TASKS[iline].FLOS = 0;
CWK_SET_TASK_LINE( CWK_TASKS[iline].CL, 0 );
}
else
CWK_TASKS[iline].MON->WON = -1;
}
}
current_task = save_current_task;
}
#define START_LINE 4
#define LINES 8
static void scroll_tasks()
{
int ch, iline, cur_task, Active_Tasks = 0;
int stay_flag;
char msg[100];
int First_Task_On_Screen = 1;
sprintf( msg,"Task # Task Type File Line # Stat WON Exe %1.1c", '%');
CWK_PRINT_CONTROL_LINE( START_LINE - 1, msg );
Active_Tasks = print_control_lines( First_Task_On_Screen );
iline = START_LINE;
CWK_PRINT_CONTROL_LINE(iline, "->");
stay_flag = 1;
while (stay_flag) {
ch = getch();
switch (ch ) {
case UPARROW :
CWK_PRINT_CONTROL_LINE(iline, " ");
if ( --iline < START_LINE ) {
if ( First_Task_On_Screen != 1 ) {
First_Task_On_Screen -= (LINES - 1);
Active_Tasks = print_control_lines( First_Task_On_Screen );
}
iline = START_LINE;
}
CWK_PRINT_CONTROL_LINE(iline, "->");
break;
case DOWNARROW :
CWK_PRINT_CONTROL_LINE(iline, " ");
if ( ++iline >= (START_LINE + Active_Tasks) ) {
if ( iline <= LINES + START_LINE - 1 )
iline = START_LINE + Active_Tasks - 1;
else {
First_Task_On_Screen += (LINES - 1);
Active_Tasks = print_control_lines( First_Task_On_Screen );
iline = START_LINE;
}
}
CWK_PRINT_CONTROL_LINE(iline, "->");
break;
case 't' :
case 'T' :
cur_task = iline - START_LINE + First_Task_On_Screen;
if ( CWK_TASKS[cur_task].MON->WON == 1 )
CWK_TASKS[cur_task].MON->WON = -1;
else if (( CWK_TASKS[cur_task].MON->WON == 0 ) ||
( CWK_TASKS[cur_task].MON->WON == -1 ) )
CWK_TASKS[cur_task].MON->WON = 1;
sprintf( msg, "-> %2.2d %-15.15s %-15.15s %4d %1.1c %-3.3s %3.2f ",
cur_task, CWK_TASKS[cur_task].TN,
CWK_TASKS[cur_task].FD->FN,
CWK_TASKS[cur_task].CL,
CWK_TASKS[cur_task].ST,
( CWK_TASKS[cur_task].MON->WON == 1) ? "yes" : "no",
(float) CWK_TASKS[cur_task].Cur_Time /
(float)Run_Current_Time );
CWK_PRINT_CONTROL_LINE(iline, msg);
break;
case ESC :
stay_flag = 0;
break;
default :
break;
}
}
CWK_DEL_CONTROL();
}
int
print_control_lines( First_Task_On_Screen )
int First_Task_On_Screen;
{
int iline, Active_Tasks = 0;
char msg[80];
for ( iline=START_LINE; iline < LINES + START_LINE; ++iline ){
sprintf( msg, "%67s", " ");
CWK_PRINT_CONTROL_LINE( iline, msg );
}
for ( iline=First_Task_On_Screen;
iline < MAX_TSKS && (iline - First_Task_On_Screen) < LINES;
iline++ )
{
if ( CWK_TASKS[iline].TN == NULL )
continue;
Active_Tasks++;
sprintf( msg, " %2.2d %-15.15s %-15.15s %4d %1.1c %-3.3s %3.2f ",
iline, CWK_TASKS[iline].TN,
CWK_TASKS[iline].FD->FN,
CWK_TASKS[iline].CL,
CWK_TASKS[iline].ST,
( CWK_TASKS[iline].MON->WON == 1) ? "yes" : "no",
(float) CWK_TASKS[iline].Cur_Time /
(float)Run_Current_Time );
CWK_PRINT_CONTROL_LINE( iline+START_LINE-First_Task_On_Screen,
msg );
}
return Active_Tasks;
}
#undef LINES
#undef START_LINE
/***********************************************************************/
void CWK_GET_KEY( other_stop )
int other_stop;
{
int ch = 0;
if ( other_stop == -1 ) {
if (kbhit()) {
ch = getch();
}
}
else if ( ( step_monitor ) || ( other_stop ) ){
ch = getch();
}
else if (kbhit()) {
ch = getch();
}
if ( ch != 0 ) {
switch ( ch ) {
case CTRL_L :
step_monitor = ++step_monitor % 2;
break;
case UPARROW :
step_rate--;
if ( step_rate < 0 )
step_rate = 0;
break;
case DOWNARROW :
step_rate++;
if ( step_rate >= MAX_DELAY )
step_rate = MAX_DELAY - 1;
break;
case CTRL_A :
print_status();
break;
case CTRL_B :
CWK_STOP_MONITORING();
break;
case CTRL_D :
case F10 :
if ( task_monitor )
CWK_TASK_SETUP();
else
CWK_SEQ_SETUP();
break;
case CTRL_H :
print_help();
break;
case CTRL_K :
print_license();
break;
case CTRL_R :
Large_Monitor = ++Large_Monitor % 2;
CWK_Resize_Window();
break;
case CTRL_T :
task_step = ++task_step % 2;
break;
case ESC :
CWK_CLEANUP_MON(1);
break;
default :
break;
}
}
}
CWK_TIME_TASK()
{
int iline;
Run_Total_Time++; Run_Current_Time++;
CWK_TASKS[current_task].Tot_Time++; CWK_TASKS[current_task].Cur_Time++;
busy_wait(step_rate);
if ( ( Run_Total_Time % Time_To_Read_Key ) == 0 )
{
CWK_GET_KEY(-1);
if ( monitor_exec_time )
{
if ( ( Run_Total_Time % (Time_To_Read_Key * 10)) == 0 )
CWK_REPORT_TIME( Run_Total_Time );
}
}
if ( ( Run_Total_Time % Exec_Report_Time ) == 0 )
{
if ( monitor_type == 2 )
CWK_Next_Pct_Rpt();
Run_Current_Time = 0;
for ( iline = 0; iline < MAX_TSKS; ++iline ) {
if ( CWK_TASKS[iline].TN != NULL )
CWK_TASKS[iline].Cur_Time = 0;
}
}
}
/***********************************************************************/
/* This routine turns off the monitoring windows. */
/***********************************************************************/
CWK_STOP_MONITORING()
{
int iline;
/* Stop the monitoring of the lines */
if ( monitor_type == 1 )
{
CWK_ERASE_ALL_MON_WIN();
for ( iline = 1; iline < MAX_TSKS; ++iline ) {
if ( CWK_TASKS[iline].TN != NULL )
CWK_TASKS[iline].MON->WON = -1;
}
}
/* Stop the monitoring of execution percentage */
else if ( monitor_type == 2 )
{
CWK_DEL_EXEC_PCT();
}
monitor_type = 0;
}
/***********************************************************************/
/* CWK_Next_Pct_Rpt reports the Pct of CPU time run since the last */
/* report. */
/***********************************************************************/
CWK_Next_Pct_Rpt()
{
char msg[81], msg1[81];
int iline;
CWK_EXEC_PCT();
for ( iline = 0; iline < ( MAX_TSKS / 4 ); ++iline )
{
msg[0] = '\0';
if ( CWK_TASKS[(4*iline)+1].TN != NULL )
{
sprintf( msg, "%2.2d %-7.7s %1.1c %3.2f ",
(4*iline)+1, CWK_TASKS[(4*iline)+1].TN,
CWK_TASKS[(4*iline)+1].ST,
(float) CWK_TASKS[(4*iline)+1].Cur_Time /
(float)Run_Current_Time );
}
if ( CWK_TASKS[(4*iline)+2].TN != NULL )
{
sprintf( msg1, "%2.2d %-7.7s %1.1c %3.2f ",
(4*iline)+2, CWK_TASKS[(4*iline)+2].TN,
CWK_TASKS[(4*iline)+2].ST,
(float) CWK_TASKS[(4*iline)+2].Cur_Time /
(float)Run_Current_Time );
strcat( msg, msg1 );
}
if ( CWK_TASKS[(4*iline)+3].TN != NULL )
{
sprintf( msg1, "%2.2d %-7.7s %1.1c %3.2f ",
(4*iline)+3, CWK_TASKS[(4*iline)+3].TN,
CWK_TASKS[(4*iline)+3].ST,
(float) CWK_TASKS[(4*iline)+3].Cur_Time /
(float)Run_Current_Time );
strcat( msg, msg1 );
}
if ( CWK_TASKS[(4*iline)+4].TN != NULL )
{
sprintf( msg1, "%2.2d %-7.7s %1.1c %3.2f ",
(4*iline)+4, CWK_TASKS[(4*iline)+4].TN,
CWK_TASKS[(4*iline)+4].ST,
(float) CWK_TASKS[(4*iline)+4].Cur_Time /
(float)Run_Current_Time );
strcat( msg, msg1 );
}
CWK_EXEC_PRINT_LINE( iline+2, msg );
}
}
/***********************************************************************/
/* CWK_Exception_Raised reports exceptions to the screen when running*/
/* the monitor. */
/***********************************************************************/
CWK_Exception_Raised( task_id, msg )
int task_id;
char *msg;
{
if ( ! task_monitor )
{
CWK_Report_Exception( "main", msg );
return;
}
else
{
if ( task_id == 0 )
task_id = current_task;
if ( exception_trace )
CWK_Report_Exception( CWK_TASKS[task_id].TN, msg );
}
}